﻿
Option Strict On
Imports Microsoft.Win32
Imports System.Security.Permissions
Imports System.Security.AccessControl
Imports System
Imports System.Reflection
Imports System.Security.Principal
Imports System.Text
''' <summary>
''' The object of Registry key about Sims3
''' </summary>
''' <remarks></remarks>
Public Class TS3Key
    ''' <summary>
    ''' Create a new registrykey of TS3
    ''' </summary>
    ''' <param name="PackName">Name of the pack in registry</param>
    ''' <remarks></remarks>
    Public Sub New(ByVal PackName As String)
        Me.PackName = PackName
    End Sub


    Private Property RegKey As RegistryKey
        Set(value As RegistryKey)
            MainRegKey = value
            Dim newKey As RegistryKey = Registry.LocalMachine.OpenSubKey(MainRegKey.Name.Replace("HKEY_LOCAL_MACHINE\", ""), True)
            If newKey.GetValueNames.Contains("ErgcRegPath") = True Then
                Dim strErgc As String = newKey.GetValue("ErgcRegPath").ToString.Replace("\ergc", "")
                'SubRegKey = Registry.LocalMachine.OpenSubKey("\SOFTWARE\" & strErgc, RegistryKeyPermissionCheck.ReadWriteSubTree, Security.AccessControl.RegistryRights.ChangePermissions)
                SubRegKey = Registry.LocalMachine.OpenSubKey("SOFTWARE\" & strErgc, False)
            Else
                SubRegKey = Registry.LocalMachine.OpenSubKey(value.Name.Replace("HKEY_LOCAL_MACHINE\SOFTWARE\", "SOFTWARE\Electronic Arts\"), False)

            End If

        End Set
        Get
            Return MainRegKey
        End Get
    End Property

    ''' <summary>
    ''' Set the permission to read certain pack key
    ''' </summary>
    ''' <value>Boolean, i.e. True or False</value>
    ''' <remarks>Will add permission  to the certain key</remarks>
    Public Property isEnabled As Boolean
        Set(value As Boolean)
            If value = False Then
                Dim wi As WindowsIdentity = WindowsIdentity.GetCurrent()
                Dim wp As WindowsPrincipal = New WindowsPrincipal(wi)

                Dim user As String = Environment.UserDomainName & "\" & Environment.UserName

                Dim rs As New RegistrySecurity()
                rs.AddAccessRule(New RegistryAccessRule(wp.Identity.Name, RegistryRights.ReadKey, AccessControlType.Deny))

                MainRegKey = Registry.LocalMachine.OpenSubKey(MainRegKey.Name.Replace("HKEY_LOCAL_MACHINE\", ""), RegistryKeyPermissionCheck.ReadWriteSubTree, Security.AccessControl.RegistryRights.ChangePermissions)
                SubRegKey = Registry.LocalMachine.OpenSubKey(SubRegKey.Name.Replace("HKEY_LOCAL_MACHINE\", ""), RegistryKeyPermissionCheck.ReadWriteSubTree, Security.AccessControl.RegistryRights.ChangePermissions)


                MainRegKey.SetAccessControl(rs)
                If SubRegKey IsNot Nothing Then
                    SubRegKey.SetAccessControl(rs)
                End If
            Else
                Dim wi As WindowsIdentity = WindowsIdentity.GetCurrent()
                Dim wp As WindowsPrincipal = New WindowsPrincipal(wi)

                Dim rs As New RegistrySecurity()
                rs.AddAccessRule(New RegistryAccessRule(wp.Identity.Name, RegistryRights.ReadKey, AccessControlType.Allow))

                MainRegKey = Registry.LocalMachine.OpenSubKey(MainRegKey.Name.Replace("HKEY_LOCAL_MACHINE\", ""), RegistryKeyPermissionCheck.ReadWriteSubTree, Security.AccessControl.RegistryRights.ChangePermissions)
                SubRegKey = Registry.LocalMachine.OpenSubKey(SubRegKey.Name.Replace("HKEY_LOCAL_MACHINE\", ""), RegistryKeyPermissionCheck.ReadWriteSubTree, Security.AccessControl.RegistryRights.ChangePermissions)
                

                MainRegKey.SetAccessControl(rs)

                If SubRegKey IsNot Nothing Then
                    SubRegKey.SetAccessControl(rs)
                End If
   

                
            End If
        End Set
        Get
            Dim wi As WindowsIdentity = WindowsIdentity.GetCurrent()
            Dim wp As WindowsPrincipal = New WindowsPrincipal(wi)
            Dim rs As RegistrySecurity = RegKey.GetAccessControl()
            Dim rl As RegistryAccessRule = New RegistryAccessRule(wp.Identity.Name, RegistryRights.ReadKey, AccessControlType.Deny)
            For Each regRule As RegistryAccessRule In rs.GetAccessRules(True, True, New NTAccount(WindowsIdentity.GetCurrent().Name).GetType)
                If regRule.Equals(rl) = True Then
                    Return False
                End If
            Next
            Return True
        End Get
    End Property
    ''' <summary>
    ''' Controls which pack to read
    ''' </summary>
    ''' <value>the name of the pack. e.g. The Sims 3 Ambitions</value>
    ''' <returns>the name of certain pack</returns>
    ''' <remarks>Most important part of this class</remarks>
    Public Property PackName As String
        Get
            If RegKey.Name <> "" Then
                Dim strName As String = RegKey.Name
                strName = strName.Split(CChar("\"))(CType(strName.Split(CChar("\")), ICollection).Count - 1)
                Return strName
            Else

                Return Nothing
            End If
            
        End Get
        Set(value As String)
            If value.ToLower.Contains("sims") = True Then
                RegKey = Registry.LocalMachine.OpenSubKey("SOFTWARE\Sims\" & value, RegistryKeyPermissionCheck.ReadWriteSubTree, Security.AccessControl.RegistryRights.ChangePermissions)
            End If

        End Set
    End Property

    ''' <summary>
    ''' Returns the install directory of certain pack
    ''' </summary>
    ''' <value>string</value>
    ''' <returns>the dir of certain pack</returns>
    ''' <remarks></remarks>
    Public ReadOnly Property InstallDir As String
        Get
            Dim newRegkey As RegistryKey = Registry.LocalMachine.OpenSubKey("SOFTWARE\Sims\" & PackName, CType(False, RegistryKeyPermissionCheck), RegistryRights.ReadKey)
            Dim strInstallDir As String = newRegkey.GetValue("Install Dir").ToString
            Return strInstallDir
        End Get
    End Property


    ''' <summary>
    ''' Returns the exe path of certain pack
    ''' </summary>
    ''' <value>string</value>
    ''' <returns>the exe path of certain pack</returns>
    ''' <remarks></remarks>
    Public ReadOnly Property ExePath As String
        Get
            Dim newRegkey As RegistryKey = Registry.LocalMachine.OpenSubKey("SOFTWARE\Sims\" & PackName, CType(False, RegistryKeyPermissionCheck), RegistryRights.ReadKey)
            Dim strExePath As String = newRegkey.GetValue("ExePath").ToString
            Return strExePath
        End Get
    End Property

    Private MainRegKey As RegistryKey
    Private SubRegKey As RegistryKey

    ''' <summary>
    ''' Close the TS3Key
    ''' </summary>
    ''' <remarks></remarks>
    Public Sub Close()
        MainRegKey.Close()
        SubRegKey.Close()
    End Sub

    ''' <summary>
    ''' Get or set the local value
    ''' </summary>
    ''' <value>string</value>
    ''' <returns>the name of language(from dictionary)</returns>
    ''' <remarks></remarks>
    Public Property local As String
        Get
            Dim newRegkey As RegistryKey = Registry.LocalMachine.OpenSubKey("SOFTWARE\Sims\" & PackName, CType(False, RegistryKeyPermissionCheck), RegistryRights.ReadKey)
            Dim strLocalName As String = newRegkey.GetValue("Locale").ToString
            strLocalName = Locales.Item(strLocalName)
            Return strLocalName
        End Get
        Set(value As String)
            Dim strLocal As String = ""
            For Each searchValue As String In Locales.Keys

                If Locales(searchValue) = value Then
                    strLocal = searchValue
                End If
            Next
            Dim newRegkey As RegistryKey = Registry.LocalMachine.OpenSubKey("SOFTWARE\Sims\" & PackName, True)
            newRegkey.SetValue("Locale", strLocal)

        End Set
    End Property




    ''' <summary>
    ''' Returns the type of certain pack, i.e. EP or SP
    ''' </summary>
    ''' <value>string</value>
    ''' <returns>the type of pack</returns>
    ''' <remarks></remarks>
    Public ReadOnly Property PackType As PackTypeName
        Get
            Dim strType As PackTypeName
            If ContentID.ToLower.Contains("ep") = True Then
                strType = PackTypeName.EP
            ElseIf ContentID.ToLower.Contains("sp") = True Then
                strType = PackTypeName.SP
            ElseIf ContentID = "Sims3" = True Then
                strType = PackTypeName.Base
            End If
            Return strType
        End Get
    End Property

    ''' <summary>
    ''' Returns the ContnetID of ceratin pack. Note: EP01 and SP01 don't have this value, so it will return a faked ContentID in order to get PackType
    ''' </summary>
    ''' <value>string</value>
    ''' <returns>The value of ContentID</returns>
    ''' <remarks>I hate EA's insane previous version of registrykey</remarks>
    Public ReadOnly Property ContentID As String
        Get
            Dim newRegkey As RegistryKey = Registry.LocalMachine.OpenSubKey("SOFTWARE\Sims\" & PackName, CType(False, RegistryKeyPermissionCheck), RegistryRights.ReadKey)
            Dim strContentID As String = ""
            If newRegkey.GetValueNames.Contains("ContentID") = True Then
                strContentID = newRegkey.GetValue("ContentID").ToString
            Else
                If newRegkey.GetValue("DisplayName").ToString.Contains("World Adventures") = True Then
                    strContentID = "sims3_ep01_sku" & newRegkey.GetValue("SKU").ToString
                ElseIf newRegkey.GetValue("DisplayName").ToString.Contains("High End Loft Stuff") = True Then
                    strContentID = "sims3_sp01_sku" & newRegkey.GetValue("SKU").ToString
                ElseIf newRegkey.GetValue("DisplayName").ToString = "The Sims 3" Then
                    strContentID = "Sims3"
                End If
            End If

            Return strContentID
        End Get
    End Property


    Private Shared Locales As New Dictionary(Of String, String)() From { _
    {"en-US", "English"},
    {"zh-CN", "Chinese (Simplified)"},
    {"zh-TW", "Chinese (Traditional)"},
    {"cs-CZ", "Czech"},
    {"da-DK", "Danish"},
    {"nl-NL", "Dutch"},
    {"fi-FI", "Finnish"}, _
    {"fr-FR", "French"}, _
    {"de-DE", "German"}, _
    {"el-GR", "Greek"}, _
    {"hu-HU", "Hungarian"},
    {"it-IT", "Italian"},
    {"ja-JP", "Japanese"},
    {"ko-KR", "Korean"},
    {"no-NO", "Norwegian"},
    {"pl-PL", "Polish"},
    {"pt-PT", "Portuguese(Portugal)"},
    {"pt-BR", "Portuguese(Brazil)"},
    {"ru-RU", "Russian"},
    {"es-ES", "Spanish(Spain)"},
    {"es-MX", "Spanish(Mexico)"},
    {"sv-SE", "Swedish"},
    {"th-TH", "Thai"}}

End Class

''' <summary>
''' The type of the Pack i.e. Base, EP, or SP
''' </summary>
''' <remarks></remarks>
Public Enum PackTypeName
    Base = 0
    EP = 1
    SP = 2
End Enum
